Shader "Unlit/Lesson68_Attenuation"
{
    Properties
    {
        _MainColor("MainColor", Color) = (1,1,1,1)
        _SpecularColor("SpecularColor", Color) = (1,1,1,1)
        _SpecularNum("SpecularNum", Range(0, 20)) = 1
    }
    SubShader
    {
        Pass
        {
            Tags
            {
                "LightMode"="ForwardBase"
            }
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fwdbase

            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            #include "AutoLight.cginc"

            fixed4 _MainColor;
            fixed4 _SpecularColor;
            float _SpecularNum;

            struct v2f
            {
                float4 pos:SV_POSITION;

                float3 wNormal:NORMAL;

                float3 wPos:TEXCOORD0;
                SHADOW_COORDS(2)
            };

            fixed3 getLambertFColor(in float3 wNormal)
            {
                float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);

                fixed3 color = _LightColor0.rgb * _MainColor.rgb * max(0, dot(wNormal, lightDir));

                return color;
            }

            fixed3 getSpecularColor(in float3 wPos, in float3 wNormal)
            {
                float3 viewDir = normalize(UnityWorldSpaceViewDir(wPos));


                float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);

                float3 halfA = normalize(viewDir + lightDir);

                fixed3 color = _LightColor0.rgb * _SpecularColor.rgb * pow(max(0, dot(wNormal, halfA)), _SpecularNum);

                return color;
            }

            v2f vert(appdata_base v)
            {
                v2f v2fData;

                v2fData.pos = UnityObjectToClipPos(v.vertex);

                v2fData.wNormal = UnityObjectToWorldNormal(v.normal);

                v2fData.wPos = mul(unity_ObjectToWorld, v.vertex).xyz;

                TRANSFER_SHADOW(v2fData);

                return v2fData;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                fixed3 lambertColor = getLambertFColor(normalize(i.wNormal));
                fixed3 specularColor = getSpecularColor(i.wPos, normalize(i.wNormal));


                UNITY_LIGHT_ATTENUATION(atten, i, i.wPos)

                fixed3 blinnPhongColor = UNITY_LIGHTMODEL_AMBIENT.rgb + (lambertColor + specularColor) * atten;
                return fixed4(blinnPhongColor.rgb, 1);
            }
            ENDCG
        }


        Pass
        {
            Tags
            {
                "LightMode"="ForwardAdd"
            }

            Blend One One

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            //如果想要附加通道也产生阴影，#pragma multi_compile_fwdadd需要修改为#pragma multi_compile_fwdadd_fullshadows
            //这样Unity会自动生成支持和不支持的shader变体
            //此而为额外的逐像素光源计算阴影，并传递给Shader
            #pragma multi_compile_fwdadd_fullshadows

            #include "UnityCG.cginc"
            #include "Lighting.cginc"
            #include "AutoLight.cginc"


            fixed4 _MainColor;
            fixed4 _SpecularColor;
            float _SpecularNum;


            struct v2f
            {
                float4 pos:SV_POSITION;

                float3 wNormal:NORMAL;

                float3 wPos:TEXCOORD0;

                SHADOW_COORDS(2)
            };

            v2f vert(appdata_base v)
            {
                v2f v2fData;

                v2fData.pos = UnityObjectToClipPos(v.vertex);

                v2fData.wNormal = UnityObjectToWorldNormal(v.normal);

                v2fData.wPos = mul(unity_ObjectToWorld, v.vertex).xyz;


                TRANSFER_SHADOW(v2fData);

                return v2fData;
            }

            fixed4 frag(v2f i) : SV_Target
            {
                fixed3 worldNormal = normalize(i.wNormal);

                #if defined(_DIRECTIONAL_LIGHT)
                    fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
                #else
                fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz - i.wPos);
                #endif
                fixed3 diffuse = _LightColor0.rgb * _MainColor.rgb * max(0, dot(worldNormal, worldLightDir));

                fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.wPos.xyz);
                fixed3 halfDir = normalize(worldLightDir + viewDir);
                fixed3 specular = _LightColor0.rgb * _SpecularColor.rgb * pow(
                    max(0, dot(worldNormal, halfDir)), _SpecularNum);
                UNITY_LIGHT_ATTENUATION(atten, i, i.wPos)
                return fixed4((diffuse + specular) * atten, 1);
            }
            ENDCG
        }
    }

    FallBack "Specular"
}